package org.linlinjava.litemall.wx.service;

import com.aliyuncs.utils.StringUtils;
import com.github.pagehelper.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.MapUtils;
import org.linlinjava.litemall.core.dto.QcodeDto;
import org.linlinjava.litemall.core.qcode.QCodeService;
import org.linlinjava.litemall.core.util.CommonUtils;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallActivityGroupon;
import org.linlinjava.litemall.db.domain.LitemallActivityRules;
import org.linlinjava.litemall.db.domain.UserVo;
import org.linlinjava.litemall.db.domain.dto.ActivityGrouponDto;
import org.linlinjava.litemall.db.domain.vo.LitemallActivityGrouponVo;
import org.linlinjava.litemall.db.service.ActivityGrouponService;
import org.linlinjava.litemall.db.service.LitemallActivityRulesService;
import org.linlinjava.litemall.db.service.LitemallUserService;
import org.linlinjava.litemall.wx.vo.GrouponRuleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author ： hejiaming
 * @createtime ： 2021-03-18 12:01
 * @description ： H5的团购信息
 */
@Service
public class WxActivityService {

    @Autowired
    private ActivityGrouponService activityGrouponService;

    @Autowired
    private LitemallActivityRulesService litemallActivityRulesService;

    @Autowired
    private QCodeService qCodeService;

    @Autowired
    private LitemallUserService litemallUserService;

    public Object grouponListBySubject(ActivityGrouponDto dto, Integer userId) {
        if (dto.getActivityId() == null) {
            return ResponseUtil.fail(900, "活动id不能为空");
        }

        List<LitemallActivityGroupon> activityGroups =
                activityGrouponService.pageQuery(dto.getTag(), dto.getActivityId(), userId,
                        null, dto.getSubjectId(), "", dto.getGrouponCode(), dto.getUserName(),
                        LitemallActivityGroupon.StateEnum.SUCCESS.getCode(),
                        dto.getPage(), dto.getLimit(), "add_time", "desc");
        if (CollectionUtils.isEmpty(activityGroups)) {
            return ResponseUtil.okList(Collections.emptyList());
        }

        List<String> grouponCodes = activityGroups.stream().map(LitemallActivityGroupon::getGrouponCode).distinct().collect(Collectors.toList());
        Map<String, Object> map = Maps.newConcurrentMap();
        map.put("grouponCodes", grouponCodes);
        map.put("state", LitemallActivityGroupon.StateEnum.SUCCESS.getCode());
        List<LitemallActivityGroupon> grouponList = activityGrouponService.findByParams(Collections.singletonList(map));

        // 该团下有多少团员
        Map<String, List<String>> grouponImages = grouponList.stream()
                .collect(Collectors.groupingBy(LitemallActivityGroupon::getGrouponCode,
                        Collectors.mapping(LitemallActivityGroupon::getImage, Collectors.toList())));

        // 计算某一个团一共有多少人成团
        Map<String, Long> grouponMap = grouponList.stream()
                .collect(Collectors.groupingBy(LitemallActivityGroupon::getGrouponCode, Collectors.counting()));

        List<Map<String, Object>> mapList = Lists.newArrayList();
        for (LitemallActivityGroupon activityGroup : activityGroups) {
            Map<String, Object> map1 = Maps.newConcurrentMap();
            map1.put("activityId", activityGroup.getActivityId());
            map1.put("subjectId", activityGroup.getSubjectId());
            mapList.add(map1);
        }
        List<LitemallActivityRules> dbRules = litemallActivityRulesService.findByParam(mapList);
        Map<String, LitemallActivityRules> activityRuleMap = dbRules.stream()
                .collect(Collectors.toMap(it -> CommonUtils.join(CommonUtils.SPLIT_SYMBOL,
                        it.getActivityId().toString(), it.getId().toString()), Function.identity(), (k1, k2) -> k1));


        Map<String, List<LitemallActivityGroupon>> subjectGrouponMap = activityGroups.stream()
                .collect(Collectors.groupingBy(LitemallActivityGroupon::getSubject));
        for (String subject : subjectGrouponMap.keySet()) {
            List<LitemallActivityGroupon> activityGroupons = subjectGrouponMap.get(subject);

            List<LitemallActivityGrouponVo> grouponDtos = Lists.newArrayList();
            for (LitemallActivityGroupon activityGroup : activityGroups) {
                LitemallActivityGrouponVo grouponDto = new LitemallActivityGrouponVo();
                grouponDto.setUserName(activityGroup.getUserName());
                grouponDto.setGrouponCode(activityGroup.getGrouponCode());
                grouponDto.setImage(activityGroup.getImage());
                grouponDto.setGrouponId(activityGroup.getGrouponId());
                grouponDto.setSubjectId(activityGroup.getSubjectId());
                grouponDto.setSubject(activityGroup.getSubject());
                Long total = 0L;
                if (MapUtils.isNotEmpty(grouponMap)) {
                    total = grouponMap.getOrDefault(activityGroup.getGrouponCode(), 0L);
                }
                grouponDto.setTotal(total.intValue());

                String key = CommonUtils.join(CommonUtils.SPLIT_SYMBOL,
                        activityGroup.getActivityId().toString(), activityGroup.getSubjectId().toString());
                Integer gap = 0;
                Integer limited = 0;
                Set<String> strings = activityRuleMap.keySet();
                for (String k : strings) {
                    if (k.equals(key)) {
                        LitemallActivityRules rule = activityRuleMap.get(k);
                        limited = rule.getLimited();
                        gap = rule.getLimited() - total.intValue();
                    }
                }
                grouponDto.setGap(gap);
                grouponDto.setLimited(limited);
                List<String> imageList = grouponImages.getOrDefault(activityGroup.getGrouponCode(), Collections.emptyList());
                grouponDto.setGrouponSubImages(imageList);
                grouponDtos.add(grouponDto);
            }
        }

        return ResponseUtil.okList(null);
    }

    public Object activityGroups(ActivityGrouponDto dto, Integer userId) {
        if (dto.getActivityId() == null) {
            return ResponseUtil.fail(900, "活动id不能为空");
        }

        Page<LitemallActivityGroupon> activityGroups = (Page<LitemallActivityGroupon>)
                activityGrouponService.pageQuery(dto.getTag(), dto.getActivityId(), userId,
                        null, dto.getSubjectId(), "", dto.getGrouponCode(), dto.getUserName(),
                        LitemallActivityGroupon.StateEnum.SUCCESS.getCode(),
                        dto.getPage(), dto.getLimit(), "add_time", "desc");

        if (CollectionUtils.isEmpty(activityGroups)) {
            return ResponseUtil.okList(Collections.emptyList());
        }

        List<String> grouponCodes = activityGroups.stream().map(LitemallActivityGroupon::getGrouponCode).distinct().collect(Collectors.toList());
        Map<String, Object> map = Maps.newConcurrentMap();
        map.put("grouponCodes", grouponCodes);
        map.put("state", LitemallActivityGroupon.StateEnum.SUCCESS.getCode());
        List<LitemallActivityGroupon> grouponList = activityGrouponService.findByParams(Collections.singletonList(map));

        // 该团下有多少团员
        Map<String, List<String>> grouponImages = grouponList.stream()
                .collect(Collectors.groupingBy(LitemallActivityGroupon::getGrouponCode,
                        Collectors.mapping(LitemallActivityGroupon::getImage, Collectors.toList())));

        // 计算某一个团一共有多少人成团
        Map<String, Long> grouponMap = grouponList.stream()
                .collect(Collectors.groupingBy(LitemallActivityGroupon::getGrouponCode, Collectors.counting()));

        List<Map<String, Object>> mapList = Lists.newArrayList();
        for (LitemallActivityGroupon activityGroup : activityGroups) {
            Map<String, Object> map1 = Maps.newConcurrentMap();
            map1.put("activityId", activityGroup.getActivityId());
            map1.put("subjectId", activityGroup.getSubjectId());
            mapList.add(map1);
        }
        List<LitemallActivityRules> dbRules = litemallActivityRulesService.findByParam(mapList);
        Map<String, LitemallActivityRules> activityRuleMap = dbRules.stream()
                .collect(Collectors.toMap(it -> CommonUtils.join(CommonUtils.SPLIT_SYMBOL,
                        it.getActivityId().toString(), it.getId().toString()), Function.identity(), (k1, k2) -> k1));


        // 我已参与的团，查团长的头像
        Map<String, LitemallActivityGroupon> captionGrouponMap = Maps.newConcurrentMap();
        if (dto.getTag() == 2) {
            List<Integer> grouponIds = activityGroups.stream()
                    .filter(it -> !it.getGrouponId().equals(0)).map(LitemallActivityGroupon::getGrouponId).distinct().collect(Collectors.toList());
            Map<String, Object> grouponHeadMap = Maps.newConcurrentMap();
            grouponHeadMap.put("ids", grouponIds);
            List<LitemallActivityGroupon> grouponHeadResult = activityGrouponService.findByParams(Collections.singletonList(grouponHeadMap));
            captionGrouponMap = grouponHeadResult.stream()
                    .collect(Collectors.toMap(LitemallActivityGroupon::getGrouponCode, Function.identity(), (k1, k2) -> k1));
        }

        List<LitemallActivityGrouponVo> grouponDtos = Lists.newArrayList();
        for (LitemallActivityGroupon activityGroup : activityGroups) {
            LitemallActivityGrouponVo grouponDto = new LitemallActivityGrouponVo();
            grouponDto.setUserName(activityGroup.getUserName());
            grouponDto.setGrouponCode(activityGroup.getGrouponCode());
            if (dto.getTag() == 2) {
                // 我是团长，取我的头像
                if (activityGroup.getGrouponId().equals(0)) {
                    grouponDto.setImage(activityGroup.getImage());
                }
                // 我不是团长取团长的头像
                else {
                    LitemallActivityGroupon captionGroupon = captionGrouponMap.getOrDefault(activityGroup.getGrouponCode(), null);
                    grouponDto.setImage(captionGroupon.getImage());
                    grouponDto.setUserName(captionGroupon.getUserName());
                }
            } else {
                grouponDto.setImage(activityGroup.getImage());
            }

            grouponDto.setGrouponId(activityGroup.getGrouponId());
            grouponDto.setSubjectId(activityGroup.getSubjectId());
            grouponDto.setSubject(activityGroup.getSubject());
            Long total = 0L;
            if (MapUtils.isNotEmpty(grouponMap)) {
                total = grouponMap.getOrDefault(activityGroup.getGrouponCode(), 0L);
            }
            grouponDto.setTotal(total.intValue());

            String key = CommonUtils.join(CommonUtils.SPLIT_SYMBOL,
                    activityGroup.getActivityId().toString(), activityGroup.getSubjectId().toString());
            Integer gap = 0;
            Integer limited = 0;
            Set<String> strings = activityRuleMap.keySet();
            for (String k : strings) {
                if (k.equals(key)) {
                    LitemallActivityRules rule = activityRuleMap.get(k);
                    limited = rule.getLimited();
                    gap = rule.getLimited() - total.intValue();
                }
            }
            grouponDto.setGap(gap);
            grouponDto.setLimited(limited);
            List<String> imageList = grouponImages.getOrDefault(activityGroup.getGrouponCode(), Collections.emptyList());
            grouponDto.setGrouponSubImages(imageList);
            // 查某个团的信息，只返回团长的团信息，并且要判断当前用户是否已经加入该团
            if (StringUtils.isNotEmpty(dto.getGrouponCode()) && dto.getTag() == 1) {
                // 如果用户在这个团里面的话，就不让再参加这个团了，让他调用分享了
                boolean userIsJoined = grouponList.stream().anyMatch(it -> it.getUserId().equals(userId.toString()));
                grouponDto.setIsJoined(userIsJoined);
            }
            // 查全部团的信息
            else {
                grouponDto.setIsJoined(null);
            }

            grouponDtos.add(grouponDto);
        }

        List<LitemallActivityGrouponVo> sortList = grouponDtos.stream().sorted(Comparator.comparing(LitemallActivityGrouponVo::getGap).reversed()).collect(Collectors.toList());
        Page<LitemallActivityGrouponVo> voPageList = new Page<>();
        voPageList.setPages(activityGroups.getPages());
        voPageList.setPageNum(activityGroups.getPageNum());
        voPageList.setPageSize(activityGroups.getPageSize());
        voPageList.setTotal(activityGroups.getTotal());
        voPageList.addAll(sortList);
        return ResponseUtil.okList(voPageList);

    }

    public Object generateQCode(Integer userId, QcodeDto dto) {
        UserVo userVo = litemallUserService.findUserVoById(userId);
        return qCodeService.createActivityGrouponShareBase64(
                dto.getUrl(),
                dto.getHomePicUrl(),
                dto.getDesc(),
                userVo.getNickname(),
                userVo.getAvatar());
    }
}
